import LinkedList from './linkedList.js'
import { defaultEquals } from '../util.js'
import { DoublyNode } from './models/linkedListModels.js'
/**
 * 双向链表
 */
export default class DoublyLinkedList extends LinkedList {
  constructor(equalsFn = defaultEquals) {
    super(equalsFn)
    // 对链表最有一个元素的引用
    this.tail = undefined
  }

  /**
   * 重写 向链表尾部添加一个元素
   * @param {*} element
   */
  push(element) {
    const node = new DoublyNode(element)
    if (this.head == null) {
      this.head = node
      this.tail = node
    } else {
      this.tail.next = node
      node.prev = this.tail
      this.tail = node
    }
    this.count++
  }

  /**
   * 重写 在任意位置插入元素
   * @param {*} element
   * @param {number} index
   * @returns
   */
  insert(element, index) {
    if (index >= 0 && index <= this.count) {
      const node = new DoublyNode(element)
      let current = this.head
      if (index === 0) {
        if (this.head == null) {
          // NEW
          this.head = node
          this.tail = node // NEW
        } else {
          node.next = this.head
          this.head.prev = node // NEW
          this.head = node
        }
      } else if (index === this.count) {
        // last item NEW
        current = this.tail
        current.next = node
        node.prev = current
        this.tail = node
      } else {
        const previous = this.getElementAt(index - 1)
        current = previous.next
        node.next = current
        previous.next = node
        current.prev = node // NEW
        node.prev = previous // NEW
      }
      this.count++
      return true
    }
    return false
  }

  /**
   * 重写 从任意位置删除元素
   * @param {number} index
   * @returns
   */
  removeAt(index) {
    if (index >= 0 && index < this.count) {
      // current 理解为当前操作的元素
      let current = this.head
      if (index === 0) {
        this.head = current.next
        if (this.count === 1) {
          this.tail = undefined
        } else {
          this.head.prev = undefined
        }
      } else if (index === this.count - 1) {
        current = this.tail
        this.tail = current.prev
        this.tail.next = undefined
      } else {
        current = this.getElementAt(index)
        const previous = current.prev
        // 将 previous 与 current 的下一项连接起来，跳过 current
        previous.next = current.next
        current.next.prev = previous
      }
      this.count--
      return current.element
    }
    return undefined
  }

  /**
   * 重写 返回一个元素的位置
   * @param {*} element
   * @returns
   */
  indexOf(element) {
    let current = this.head
    let index = 0
    while (current != null) {
      if (this.equalsFn(element, current.element)) {
        return index
      }
      index++
      current = current.next
    }
    return -1
  }

  /**
   * 获取最有一个元素信息
   * @returns
   */
  getTail() {
    return this.tail
  }

  /**
   * 重写 清空
   */
  clear() {
    super.clear()
    this.tail = undefined
  }

  /**
   * 重写 链表转化为字符串(正)
   * @returns
   */
  toString() {
    if (this.head == null) {
      return ''
    }
    let objString = `${this.head.element}`
    let current = this.head.next
    while (current != null) {
      objString = `${objString}, ${current.element}`
      current = current.next
    }
    return objString
  }

  /**
   * 链表转化为字符串(反)
   * @returns 
   */
  inverseToString() {
    if (this.tail == null) {
      return ''
    }
    let objString = `${this.tail.element}`
    let previous = this.tail.prev
    while (previous != null) {
      objString = `${objString}, ${previous.element}`
      previous = previous.prev
    }
    return objString
  }
}
